package com.xiaokan.query;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.xiaokan.datastructures.LexiconDictionary;
import com.xiaokan.pojo.Lexicon;
import com.xiaokan.utils.BufferedRandomAccessFile;
import com.xiaokan.utils.MyProperties;
import com.xiaokan.utils.VarByte;

public class IndexWrapper {

	public final static int MAXDID = Integer.MAX_VALUE - 2;

	private String term;

	private Lexicon lex;

	private BufferedRandomAccessFile fin;

	private long curPos;

	private int lastDocId = -99999;

	private int freq = -1;

	private List<Integer> list = new ArrayList<Integer>();

	private LexiconDictionary lDict = LexiconDictionary.getInstance();

	public IndexWrapper() {
	}

	public boolean open(String term) {
		try {
			fin = new BufferedRandomAccessFile(MyProperties.INVERTED_INDEX_FILE);
			this.term = term;
			lex = lDict.getLexicon(term);
			if (lex == null)
				return false;
			fin.seek(lex.getStart());
			curPos = lex.getStart();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public int nextGEQ(int k) {
		int ret = IndexWrapper.MAXDID;
		byte b[] = new byte[10];
		int len = 0;
		list.clear();
		freq = -1;
		boolean flag = false;
		try {
			outer: while (true) {
				len = 0;
				while ((b[len++] = fin.readByte()) < 0) {
				}
				curPos += len;
				int docId = VarByte.bytes2ints(Arrays.copyOf(b, len)).get(0);
				if (lastDocId != -99999) {
					docId += lastDocId;// add difference
				}
				lastDocId = docId;
				if (docId >= k) {
					flag = true;
					ret = docId;
				}

				// Get freq
				len = 0;
				while ((b[len++] = fin.readByte()) < 0) {
				}
				curPos += len;
				freq = VarByte.bytes2ints(b).get(0);

				// skip positions
				for (int i = 0; i < freq; i++) {
					len = 0;// Get freq
					while ((b[len++] = fin.readByte()) < 0) {
					}
					curPos += len;
					if (flag) {
						list.add(VarByte.bytes2ints(Arrays.copyOf(b, len)).get(0));
					}
				}

				if (curPos >= lex.getEnd()) {
					return MAXDID;
				}
				if (flag)
					break outer;
			}
			b = null;
			return ret;
		} catch (Exception e) {
			e.printStackTrace();
			return ret;
		}
	}

	public int getFreq() {
		return freq;
	}

	public List<Integer> getPositions() {
		return list;
	}

	public void close() {
		term = null;
		lex = null;
		try {
			fin.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}
